package com.recipedb.recipedb.service.impl;

import com.recipedb.recipedb.entity.Favorite;
import com.recipedb.recipedb.entity.Recipe;
import com.recipedb.recipedb.repository.FavoriteRepository;
import com.recipedb.recipedb.service.FavoriteService;
import com.recipedb.recipedb.service.RecipeService;
import com.recipedb.recipedb.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.PageImpl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class FavoriteServiceImpl implements FavoriteService {

    private final FavoriteRepository favoriteRepository;
    private final UserService userService;
    private final RecipeService recipeService;



    @Override
    @Transactional
    public Favorite addFavorite(Long userId, Long recipeId) {
        userService.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在"));

        Recipe recipe = recipeService.findById(recipeId)
                .orElseThrow(() -> new RuntimeException("菜谱不存在"));

        if (favoriteRepository.existsByUserIdAndRecipeId(userId, recipeId)) {
            throw new RuntimeException("已收藏该菜谱");
        }

        Favorite favorite = new Favorite();
        favorite.setUserId(userId);
        favorite.setRecipeId(recipeId);
        favorite.setCreatedAt(LocalDateTime.now());

        Favorite savedFavorite = favoriteRepository.save(favorite);
        savedFavorite.setRecipe(recipe);
        return savedFavorite;
    }

    @Override
    @Transactional
    public boolean removeFavorite(Long userId, Long recipeId) {
        int deletedCount = favoriteRepository.deleteByUserIdAndRecipeId(userId, recipeId);
        return deletedCount > 0;
    }

    @Override
    public List<Favorite> getFavoritesByUserId(Long userId) {
        List<Favorite> favorites = favoriteRepository.findByUserIdOrderByCreatedAtDesc(userId);
        // 为每个收藏记录设置菜谱实体（包含收藏数）
        favorites.forEach(favorite -> {
            recipeService.findById(favorite.getRecipeId()).ifPresent(favorite::setRecipe);
        });
        return favorites;
    }

    @Override
    public List<Recipe> getFavoriteRecipesByUserId(Long userId) {
        List<Long> recipeIds = favoriteRepository.findRecipeIdsByUserId(userId);
        return recipeIds.stream()
                .map(recipeService::findById)
                .filter(Optional::isPresent)
                .map(Optional::get)
                .collect(Collectors.toList());
    }

    @Override
    public boolean isFavorite(Long userId, Long recipeId) {
        return favoriteRepository.existsByUserIdAndRecipeId(userId, recipeId);
    }

    @Override
    public Long getFavoriteCountByRecipeId(Long recipeId) {
        return favoriteRepository.countByRecipeId(recipeId);
    }

    @Override
    public Long getTotalFavoritesByUserId(Long userId) {
        return favoriteRepository.countTotalFavoritesByUserId(userId);
    }

    @Override
    public Map<Long, Long> getFavoriteCountsByRecipeIds(List<Long> recipeIds) {
        if (recipeIds == null || recipeIds.isEmpty()) {
            return new HashMap<>();
        }

        List<Object[]> results = favoriteRepository.countByRecipeIds(recipeIds);
        Map<Long, Long> favoriteCounts = new HashMap<>();

        for (Object[] result : results) {
            Long recipeId = (Long) result[0];
            Long count = ((Number) result[1]).longValue();
            favoriteCounts.put(recipeId, count);
        }

        return favoriteCounts;
    }


    // ========== 核心：收藏搜索接口（适配 Recipe 筛选逻辑） ==========
    @Override
    public Page<Favorite> searchFavorites(
            Long userId,
            String keyword,
            String tag,
            String category,
            String ingredient,
            Integer pageNum,
            Integer pageSize) {

        // 1. 参数兜底
        int page = pageNum == null || pageNum < 1 ? 0 : pageNum - 1;
        int size = pageSize == null || pageSize < 1 ? 10 : pageSize;

        // 2. 步骤1：查询用户所有收藏
        List<Favorite> allUserFavorites = favoriteRepository.findByUserIdOrderByCreatedAtDesc(userId);
        if (allUserFavorites.isEmpty()) {
            return new PageImpl<>(new ArrayList<>(), PageRequest.of(page, size), 0);
        }

        // 3. 步骤2：复用 RecipeService 的 search 方法，获取符合条件的菜谱列表
        List<Recipe> filteredRecipes = recipeService.search(keyword, tag, category, ingredient);
        if (filteredRecipes.isEmpty()) {
            return new PageImpl<>(new ArrayList<>(), PageRequest.of(page, size), 0);
        }
        // 提取符合条件的菜谱ID
        List<Long> targetRecipeIds = filteredRecipes.stream()
                .map(Recipe::getId)
                .collect(Collectors.toList());

        // 4. 步骤3：筛选用户收藏中包含这些菜谱ID的记录
        List<Favorite> filteredFavorites = allUserFavorites.stream()
                .filter(favorite -> targetRecipeIds.contains(favorite.getRecipeId()))
                .collect(Collectors.toList());

        // 5. 步骤4：手动分页
        int startIndex = page * size;
        int endIndex = Math.min(startIndex + size, filteredFavorites.size());
        List<Favorite> pagedFavorites = startIndex >= filteredFavorites.size()
                ? new ArrayList<>()
                : filteredFavorites.subList(startIndex, endIndex);

        // 6. 步骤5：填充菜谱信息（含收藏数）
        pagedFavorites.forEach(favorite -> {
            recipeService.findById(favorite.getRecipeId())
                    .map(recipeService::setFavoriteCountForRecipe)
                    .ifPresent(favorite::setRecipe);
        });

        // 7. 封装 Page 对象
        return new PageImpl<>(
                pagedFavorites,
                PageRequest.of(page, size),
                filteredFavorites.size()
        );
    }



}